# general testing program for comun, tests most of its features

0 10 "testing:" -->

exitFunc:   # tests the exit command
  0

  1 ?
    !.
  .

  ^ 1
.

unusedFunc: # function that won't be called, basic test of optimization
  1 2 3
  ?
    --
  ;
    ++
  .
.

myFunc:     # just some function
  1 2 3

  ?
    0 "abc" -->
  ;
    !.
  .
.

fact:      # recursive factorial
  ?'
    $0 -- fact *
  ;
    ^ 1
  .
.

##0         # push 0

?
  ~abc      # sneakily declare pointer in non-executed branch, shouldn't matter
  $4        # this might crash the program (if stack top is near 0 now)
  0 10 "ERROR (a)" -->
  !.
. 

$$ 2 $+0 $$ $4 -  # stack top now: 4
$' $$ >< - +

10 != ?
  0 10 "ERROR (b)" -->
  !.
.

lateFunc    # call a function that will be defined later, pushes 10

"#"         # comment in string, should be pushed
# "abc" #   # string in comment, shouldn't be pushed

+

# stack now: 45

# let's now try out most operations:
+xf +b011 - * 11 / -d02 // 50 + -10 4 %% + 1000 >< / -b100 +x3 != + $0 -1 << +
+b111 |! 1 + 0 1 2 ?? +

# 48 is here # 1 2 3 4 $ # push the 48

1 |<    # multiply by 2

96 != ?
  0 10 "ERROR (c)" -->
  !.
.

# let's try some complicated control structures:

1

?
  # here

  1 2 =
  ?
    # not here
    @
      @
        0 10 "ERROR (d)" -->
        !.
      .
      !@
    .
    ++
  ;
    # here

    7

    @@
      ?'
      ;
        @'
          !@
        .

        !@
      .

      --
    .

    0 = ?'
      3 +
    .
  .
;
  # not here

  ++

  @
    ?
      ++
      ?
        ?
          ++
        .
      .
    .
  
    @
      <-
      ++
    .
  .
.

4 != ?
  0 10 "ERROR (e)" -->
  !.
.

exitFunc

?
  0 10 "ERROR (f)" -->
  !.
.

# test pointers now:

~var0:0
~var20:20
~stBackup

~16
  ~var20     # same name but in different type env.
~0

$0>stBackup

13 $:abc     # abc is declared above

$var20>var0

20 $abc $:var0

$>var20

30 $:var20

$var20>0

+ +

$stBackup>0

$stBackup=0 +

$var0

$1=0 # should push 2
+

45 != ?
  0 10 "ERROR (g)" -->
  !.
.

5 fact 120 != ?   # test recursion
  0 10 "ERROR (h)" -->
  !.
.

# test simple goto:
>skipLabel

0 10 "ERROR (i)" -->
!.

~:skipLabel

# test type environments:

55
>8

~8
  $0 2 * ++ 3 * # should be 77
  >16
~16
  $0 10 /       # should be 7
  >32
~32
  $0 $0 *       # should be 49
  >0
~0

0 +   # these operations do nothing (test optimizations)
1 *
1 /
1 //
0 -
0 |

49 != ?
  0 10 "ERROR (j)" -->
  !.
.

0 10 "ALL SEEMS OK" -->

lateFunc:
  10
.
